package alipay

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"log"
	"yundian/internel/app/dao"
	"yundian/internel/app/helper"
	"yundian/internel/app/helper/request"
	"yundian/internel/app/helper/resphelper"
	"yundian/internel/app/logic"
	"yundian/internel/app/models/automate"
	"yundian/internel/app/models/goods"
	"yundian/internel/app/models/orders"
	"yundian/internel/app/models/prices"
	"yundian/internel/app/models/room"
	"yundian/internel/pkg/dingo"
	"yundian/internel/pkg/dingo/global"
	. "yundian/internel/pkg/dingo/result"
	"yundian/internel/pkg/utils"
)

// HandleAgainGoodsOrder 重新支付 商品订单
func HandleAgainGoodsOrder(ctx *gin.Context) {
	userId, err := helper.GetUserIdFromCtx(ctx)
	if err != nil {
		Response(ctx)(err.Error(), CodeNeedLogin, nil)(Unauthorized)
		return
	}
	// 请求参数处理
	againParam := &request.AgainStewardOrderReq{}
	dingo.ErrorIf(ctx.ShouldBindJSON(againParam)).Unwrap()

	param := &request.CreateStewardOrderReq{}
	param.ClientIp = ctx.ClientIP()
	param.UserId = userId
	param.Openid = againParam.Openid

	// 验证是否是黑名单 - 拉黑暂时只针对充电服务，充电服务的黑名单已移至小程序判断
	//if b := helper.CheckOpenidStatus(param.Openid); b {
	//	Response(ctx)("CodeInvalidOpenid", CodeInvalidOpenid, nil)(OK)
	//	return
	//}

	orderData := dao.NewGoodsDao().GetGoodsOrdersListByTradeNo(againParam.TradeNo, helper.TypeNumGoodsOrderStatusWait)
	goodsOrderList := orderData.Unwrap().([]*goods.OrderUpdate)
	if len(goodsOrderList) == 0 {
		Response(ctx)("无效订单", CodeNeedLogin, nil)(Unauthorized)
		return
	}
	if goodsOrderList[0].Status != helper.TypeNumGoodsOrderStatusWait {
		Response(ctx)("无效订单", CodeNeedLogin, nil)(Unauthorized)
		return
	}

	for _, item := range goodsOrderList {
		param.Amount += item.Amount
	}

	respData := &resphelper.AliPayTradeCreateOrderRes{}
	alipayOrderLogic := logic.NewAliPayOrderLogic()
	alipayOrderLogic.TradeNo = goodsOrderList[0].TradeNo
	param.TradeNo = goodsOrderList[0].TradeNo
	if param.Amount > 0 {
		cParam := &request.AliPayTradeCreateOrder{
			Money:      int64(param.Amount),
			DeviceSn:   param.DeviceSn,
			BuyerId:    param.Openid,
			Key:        "goods",
			PaySubject: global.Const.Desc.UnifiedGoodsBody,
		}
		if respData, err = alipayOrderLogic.AliPayTradeCreateCommon(cParam); err != nil {
			Response(ctx)("支付失败", CodeInternalServerError, nil)(OK)
			return
		}
	} else {
		_ = dao.NewGoodsDao().UpdateGoodsOrders(&goods.OrderUpdate{
			TradeNo: alipayOrderLogic.TradeNo,
			Status:  helper.TypeNumGoodsOrderStatusDonePay})
	}

	Response(ctx)("", CodeSuccess, map[string]interface{}{
		"pay":     respData,
		"order":   goodsOrderList,
		"donePay": param.Amount <= 0,
	})(OK)
}

// HandleCreateGoodsOrder 统一下单 商品订单
func HandleCreateGoodsOrder(ctx *gin.Context) {
	userId, err := helper.GetUserIdFromCtx(ctx)
	if err != nil {
		Response(ctx)(err.Error(), CodeNeedLogin, nil)(Unauthorized)
		return
	}
	// 请求参数处理
	param := &request.CreateStewardOrderReq{}
	dingo.ErrorIf(ctx.ShouldBindJSON(param)).Unwrap()
	param.ClientIp = ctx.ClientIP()
	param.UserId = userId

	if param.Openid == "" || param.DeviceSn == "" {
		Response(ctx)("参数错误,请重新扫码", CodeError, nil)(OK)
		return
	}

	// 验证是否是黑名单  - 拉黑暂时只针对充电服务，充电服务的黑名单已移至小程序判断
	//if b := helper.CheckOpenidStatus(param.Openid); b {
	//	Response(ctx)("CodeInvalidOpenid", CodeInvalidOpenid, nil)(OK)
	//	return
	//}

	// 商品校验
	if goodsInvalidList, err := dao.NewGoodsDao().CheckGoodsNum(param); err != nil {
		Response(ctx)(err.Error(), CodeInternalServerError, false)(Error)
		return
	} else if len(goodsInvalidList) > 0 {
		Response(ctx)("部分商品失效", CodeError, goodsInvalidList)(OK)
		return
	}

	//param.Key = "goods"
	//resultData := &wxpay.PayData{}
	orderLogic := logic.NewOrderLogic()
	goodsLogic := logic.NewOrderLogicGoods(param, orderLogic.TradeNo)
	if goodsLogic.Repetition {
		Response(ctx)("下单过于频繁", CodeError, false)(Error)
		return
	}
	goodsLogic.InsertOrdersLogicGoods(param)
	if len(goodsLogic.AddGoodsOrderList) == 0 {
		Response(ctx)("下单失败", CodeInternalServerError, false)(Error)
		return
	}
	if err := dao.NewGoodsDao().UpdateGoodsNum(param); err != nil {
		Response(ctx)("下单失败-数量", CodeInternalServerError, false)(Error)
		return
	}

	respData := &resphelper.AliPayTradeCreateOrderRes{}
	alipayOrderLogic := logic.NewAliPayOrderLogic()
	if goodsLogic.Amount > 0 {
		param.Amount = goodsLogic.Amount
		//respData, err := orderLogic.HandleWxStewardUnifiedOrder(param)
		//if err != nil {
		//	Response(ctx)(err.Error(), CodeError, respData)(Error)
		//	return
		//}
		//resultData = orderLogic.HandleMakeSign(respData)
		//_ = orderLogic.HandleWxStewardSetAgainOrder(orderLogic.TradeNo, resultData.ToJson())
		cParam := &request.AliPayTradeCreateOrder{
			Money:      int64(param.Amount),
			DeviceSn:   param.DeviceSn,
			BuyerId:    param.Openid,
			Key:        "goods",
			PaySubject: global.Const.Desc.UnifiedGoodsBody,
		}
		if respData, err = alipayOrderLogic.AliPayTradeCreateCommon(cParam); err != nil {
			Response(ctx)("支付失败", CodeInternalServerError, nil)(OK)
			return
		}
	} else {
		_ = dao.NewGoodsDao().UpdateGoodsOrders(&goods.OrderUpdate{
			TradeNo: orderLogic.TradeNo,
			Status:  helper.TypeNumGoodsOrderStatusDonePay})
	}

	dao.NewGoodsDao().EmptyGoodsBuyCart(&request.SetGoodsBuyCartReq{PlaceId: param.PlaceId, MemberId: userId})
	Response(ctx)("", CodeSuccess, map[string]interface{}{
		"pay":     respData,
		"order":   goodsLogic.AddGoodsOrderList,
		"donePay": goodsLogic.Amount <= 0,
	})(OK)
}

// HandleCreateRoomOrder 统一下单 续住订单
func HandleCreateRoomOrder(ctx *gin.Context) {
	userId, err := helper.GetUserIdFromCtx(ctx)
	if err != nil {
		Response(ctx)(err.Error(), CodeNeedLogin, nil)(Unauthorized)
		return
	}
	// 请求参数处理
	param := &request.CreateStewardOrderReq{}
	dingo.ErrorIf(ctx.ShouldBindJSON(param)).Unwrap()
	param.ClientIp = ctx.ClientIP()
	param.UserId = userId

	if param.Openid == "" || param.DeviceSn == "" {
		Response(ctx)("参数错误,请重新扫码", CodeError, nil)(OK)
		return
	}

	// 验证是否是黑名单  - 拉黑暂时只针对充电服务，充电服务的黑名单已移至小程序判断
	//if b := helper.CheckOpenidStatus(param.Openid); b {
	//	Response(ctx)("CodeInvalidOpenid", CodeInvalidOpenid, nil)(OK)
	//	return
	//}

	roomTypeData := dao.NewRoomDaoDao().GetRoomTypeDetails(param.RoomTypeId).Unwrap().(*request.RoomTypeListRes)
	if roomTypeData.Id == 0 || roomTypeData.Status != 1 {
		Response(ctx)("参数错误，无空房", CodeError, nil)(OK)
		return
	}

	OrderStatus := 1
	param.Amount = roomTypeData.Price - roomTypeData.DiscountsAmount
	dayLen := utils.GetDayLen(param.InTime, param.LeaveTime)
	if param.Amount <= 0 {
		param.Amount = 0
		OrderStatus = 4
	} else {
		param.Amount = param.Amount * dayLen
	}

	// 下订单业务逻辑
	//resultData := &wxpay.PayData{}
	//orderLogic := logic.NewOrderLogic()
	//if param.Amount > 0 {
	//	respData, err := orderLogic.HandleWxStewardUnifiedOrder(param)
	//	if err != nil {
	//		Response(ctx)(err.Error(), CodeError, respData)(Error)
	//		return
	//	}
	//	resultData = orderLogic.HandleMakeSign(respData)
	//}
	respData := &resphelper.AliPayTradeCreateOrderRes{}
	orderLogic := logic.NewAliPayOrderLogic()
	cParam := &request.AliPayTradeCreateOrder{
		Money:      int64(param.Amount),
		DeviceSn:   param.DeviceSn,
		BuyerId:    param.Openid,
		Key:        "room",
		PaySubject: global.Const.Desc.UnifiedRoomBody,
	}
	if respData, err = orderLogic.AliPayTradeCreateCommon(cParam); err != nil {
		Response(ctx)("支付失败", CodeInternalServerError, nil)(OK)
		return
	}

	// 创建本地订单
	orderData := dao.NewRoomDaoDao().CreateRoomOrder(&room.OrderDb{
		MemberId:        userId,
		DayLen:          dayLen,
		UserId:          roomTypeData.UserId,
		PlaceId:         roomTypeData.PlaceId,
		TypeId:          param.RoomTypeId,
		RoomId:          param.RoomId,
		DiscountsAmount: roomTypeData.DiscountsAmount,
		Price:           roomTypeData.Price,
		Amount:          param.Amount,
		Status:          uint8(OrderStatus),
		PayType:         3,
		ThirdTradeNo:    respData.AliPayTradeCreateResBody.OutTradeNo,
		TradeNo:         orderLogic.TradeNo,
		DeviceSn:        param.DeviceSn,
		UserName:        roomTypeData.UserName,
		PlaceName:       roomTypeData.PlaceName,
		InTime:          param.InTime,
		LeaveTime:       param.LeaveTime,
		MemberPhone:     param.MemberPhone,
		MemberName:      param.MemberName,
	})

	fmt.Println("CreateRoomOrder", orderData.Unwrap())
	Response(ctx)("", CodeSuccess, respData)(OK)
}

// HandleAutomateCreateGoodsOrder 创建售货订单
func HandleAutomateCreateGoodsOrder(ctx *gin.Context) {
	userId, err := helper.GetUserIdFromCtx(ctx)
	dingo.ErrorIf(err).Unwrap()

	param := &request.CreateStewardOrderReq{}
	dingo.ErrorIf(ctx.ShouldBindJSON(param)).Unwrap()
	param.ClientIp = ctx.ClientIP()
	param.UserId = userId

	if param.Openid == "" || param.DeviceSn == "" {
		Response(ctx)("参数错误,请重新扫码", CodeError, nil)(OK)
		return
	}

	// 商品校验
	goodsList := dao.NewAutomateDaoDao().GetAutomateGoodsBindList(&request.GetAutomateGoodsBindListReq{
		BaseListReq: request.BaseListReq{PageNo: 1, PageSize: 1},
		DeviceSn:    param.DeviceSn,
		RoutesId:    param.RoutesId,
		Status:      helper.TypeNumCommonStatusTrue,
		GoodsStatus: helper.TypeNumGoodsStatusYesOn,
	}).Unwrap().([]*request.GetAutomateGoodsBindListRes)
	if len(goodsList) == 0 {
		Response(ctx)("商品失效", CodeError, false)(OK)
		return
	}

	respData := &resphelper.AliPayTradeCreateOrderRes{}
	orderLogic := logic.NewAliPayOrderLogic()

	if goodsList[0].Price > 0 {
		param.Amount = goodsList[0].Price
		cParam := &request.AliPayTradeCreateOrder{
			Money:      int64(param.Amount),
			DeviceSn:   param.DeviceSn,
			BuyerId:    param.Openid,
			Key:        "automate",
			PaySubject: global.Const.Desc.UnifiedAutomateBody,
		}
		if respData, err = orderLogic.AliPayTradeCreateCommon(cParam); err != nil {
			Response(ctx)("支付失败", CodeInternalServerError, nil)(OK)
			return
		}
	}

	insertInfo := &automate.OrderDb{
		MemberId:       userId,
		UserId:         goodsList[0].UserId,
		PlaceId:        goodsList[0].PlaceId,
		AutomateGoodId: goodsList[0].AutomateGoodsId,
		Price:          goodsList[0].Price,
		Amount:         goodsList[0].Price,
		BuyNum:         1,
		RoutesId:       goodsList[0].RoutesId,
		Status:         1,
		PayType:        3,
		PlaceName:      goodsList[0].PlaceName,
		TradeNo:        orderLogic.TradeNo,
		DeviceSn:       param.DeviceSn,
		GoodsName:      goodsList[0].Name,
		GoodsIcon:      goodsList[0].Icon,
	}
	if data := dao.NewAutomateDaoDao().InsertGoodsOrder(insertInfo); data.Err != nil {
		Response(ctx)(data.Err.Error(), CodeInternalServerError, respData)(OK)
		return
	}

	//Response(ctx)("", CodeSuccess, respData)(OK)
	//Response(ctx)("", CodeSuccess, map[string]interface{}{
	//	"pay":     respData,
	//	"tradeNo": orderLogic.TradeNo,
	//	"donePay": param.Amount <= 0,
	//})(OK)

	Response(ctx)("", CodeSuccess, struct {
		*resphelper.AliPayTradeCreateOrderRes
		TradeNo string `json:"tradeNo"`
	}{
		AliPayTradeCreateOrderRes: respData,
		TradeNo:                   orderLogic.TradeNo,
	})(OK)
}

// HandleCreateChargeOrder 创建充电订单
func HandleCreateChargeOrder(ctx *gin.Context) {
	userId, err := helper.GetUserIdFromCtx(ctx)
	log.Println("打印统一下订单，请求参数处理", userId, err)
	if err != nil {
		Response(ctx)(err.Error(), CodeNeedLogin, nil)(Unauthorized)
		return
	}
	// 请求参数处理
	param := &request.CreateOrderReq{}
	dingo.ErrorIf(ctx.ShouldBindJSON(param)).Unwrap()
	param.ClientIp = ctx.ClientIP()
	param.UserId = userId

	log.Println("打印统一下订单，请求参数处理", param)

	if param.Openid == "" || param.DeviceSn == "" {
		Response(ctx)("参数错误,请重新扫码", CodeError, nil)(OK)
		return
	}

	// 判断是否有订单
	orderInfo := dao.NewOrderDao().GetOrderInfoByOpenidAndSn(param.Openid, param.DeviceSn).Unwrap().(*orders.OrderModel)
	if orderInfo.State == 2 {
		Response(ctx)("CodeOrderExits", CodeOrderExits, orderInfo)(OK)
		return
	}

	// 下订单业务逻辑
	client := &logic.OrderLogic{}
	cParam := &request.AliPayTradeCreateOrder{
		Money:     client.GetDeviceMoney(param),
		DeviceSn:  param.DeviceSn,
		ProductId: param.ProductId,
		BuyerId:   param.Openid,
	}
	aliPayOrderLogic := logic.NewAliPayOrderLogic()
	respData, err := aliPayOrderLogic.AliPayTradeCreate(cParam)
	if err != nil {
		log.Println("创建一收单交易创建失败", err, respData)
		Response(ctx)("统一收单交易创建失败", CodeSuccess, nil)(Error)
		return
	}

	Response(ctx)("", CodeSuccess, respData)(OK)
}

// GetUserAgreementSign GET用户周期扣款签约
func GetUserAgreementSign(c *gin.Context) {
	userId, err := helper.GetUserIdFromCtx(c)
	dingo.ErrorIf(err).Unwrap()

	orderResult := dao.NewOrderAutoRenewDao().GetAutoRenewMonthly(userId, true)
	orderInfo := orderResult.Unwrap().(*request.GetAutoRenewMonthlyReq)
	if orderResult.Err != nil {
		Response(c)("", CodeInternalServerError, nil)(OK)
		return
	}

	orderInfo.CloseNum = dao.NewOrderAutoRenewDao().GetAutoRenewMonthlyCloseCount(userId).Unwrap().(int64)

	Response(c)("", CodeSuccess, orderInfo)(OK)
}

// UserAgreementSign 用户周期扣款签约
func UserAgreementSign(c *gin.Context) {

	userId, err := helper.GetUserIdFromCtx(c)
	dingo.ErrorIf(err).Unwrap()

	// 请求参数处理
	param := &request.AliPayUserAgreementSignRes{}
	dingo.ErrorIf(c.ShouldBindJSON(&param)).Unwrap()
	param.UserId = userId
	param.Money = 300
	priceInfo := dao.NewPricesDao().GetPriceDetail(param.ProductId).Unwrap().(*prices.PriceModel)
	if priceInfo.Id > 0 {
		param.Money = priceInfo.PayMoney
	}

	log.Println("打印统一收单交易创建接口，请求参数处理", userId, param)

	if param.PlaceId == 0 || param.DeviceSn == "" {
		Response(c)("参数错误,请重新扫码", CodeError, nil)(OK)
		return
	}

	// 校验是否己开通服务
	orderResult := dao.NewOrderAutoRenewDao().GetAutoRenewMonthly(userId, true)
	orderInfo := orderResult.Unwrap().(*request.GetAutoRenewMonthlyReq)
	if orderResult.Err != nil {
		Response(c)("", CodeInternalServerError, nil)(OK)
		return
	}
	if orderInfo.Id > 0 && orderInfo.Status != 2 {
		Response(c)("己开通包月订单", CodeError, nil)(OK)
		return
	}

	if dao.NewOrderAutoRenewDao().GetAutoRenewMonthlyCloseCount(userId).Unwrap().(int64) > 0 {
		Response(c)("未授权，无法开通", CodeError, nil)(OK)
		return
	}

	// 下订单业务逻辑
	aliPayOrderLogic := logic.NewAliPayOrderLogic()
	respData, err := aliPayOrderLogic.AliPayUserAgreementSign(param)
	if err != nil {
		log.Println("周期扣款签约 创建一收单交易创建失败", err, respData)
		Response(c)("周期扣款签约 统一收单交易创建失败", CodeInternalServerError, nil)(Error)
		return
	}

	// 创建支付订单
	if dao.NewOrderAutoRenewDao().CreateAutoRenewMonthly(param, aliPayOrderLogic.TradeNo).Err != nil {
		Response(c)("", CodeInternalServerError, nil)(OK)
		return
	}

	Response(c)("", CodeSuccess, respData)(OK)
}

// APP 统一收单交易创建接口
func AppTradeCreate(c *gin.Context) {

	userId, err := helper.GetUserIdFromCtx(c)
	if err != nil {
		Response(c)(err.Error(), CodeNeedLogin, nil)(Unauthorized)
		return
	}
	// 请求参数处理
	param := &request.AliPayTradeCreateOrder{}
	dingo.ErrorIf(c.Bind(param)).Unwrap()
	param.UserId = userId

	//userId := 2

	log.Println("打印统一收单交易创建接口，请求参数处理", userId, param)

	if param.BuyerId == "" || param.DeviceSn == "" || param.Money <= 0 {
		Response(c)("参数错误,请重新扫码", CodeError, nil)(OK)
		return
	}

	// 判断是否有订单
	orderInfo := dao.NewOrderDao().GetOrderInfoByOpenidAndSn(param.BuyerId, param.DeviceSn).Unwrap().(*orders.OrderModel)
	if orderInfo.State == 2 { // 100007
		Response(c)("CodeOrderExits", CodeOrderExits, orderInfo)(OK)
		return
	}

	//下订单业务逻辑
	aliPayOrderLogic := logic.NewAliPayOrderLogic()
	respData, err := aliPayOrderLogic.AppAliPayTradeCreate(param)
	if err != nil {
		log.Println("APP 创建一收单交易创建失败", err, respData)
		Response(c)("App 统一收单交易创建失败", CodeInternalServerError, nil)(Error)
		return
	}
	Response(c)("", CodeSuccess, respData)(OK)
}

// 支付宝 -- 统一收单交易创建接口
func TradeCreate(c *gin.Context) {

	userId, err := helper.GetUserIdFromCtx(c)
	if err != nil {
		Response(c)(err.Error(), CodeNeedLogin, nil)(Unauthorized)
		return
	}
	// 请求参数处理
	param := &request.AliPayTradeCreateOrder{}
	dingo.ErrorIf(c.Bind(param)).Unwrap()
	param.UserId = userId

	//userId := 2

	log.Println("打印统一收单交易创建接口，请求参数处理", userId, param)

	if param.BuyerId == "" || param.DeviceSn == "" || param.Money <= 0 {
		Response(c)("参数错误,请重新扫码", CodeError, nil)(OK)
		return
	}

	// 判断是否有订单
	orderInfo := dao.NewOrderDao().GetOrderInfoByOpenidAndSn(param.BuyerId, param.DeviceSn).Unwrap().(*orders.OrderModel)
	if orderInfo.State == 2 { // 100007
		Response(c)("CodeOrderExits", CodeOrderExits, orderInfo)(OK)
		return
	}

	//下订单业务逻辑
	aliPayOrderLogic := logic.NewAliPayOrderLogic()
	respData, err := aliPayOrderLogic.AliPayTradeCreate(param)
	if err != nil {
		log.Println("创建一收单交易创建失败", err, respData)
		Response(c)("统一收单交易创建失败", CodeSuccess, nil)(Error)
		return
	}
	Response(c)("", CodeSuccess, respData)(OK)
}

//资金授权解冻接口
func OrderUnfreeze(c *gin.Context) {
	param := &request.OrderUnfreezeReq{}
	dingo.ErrorIf(c.Bind(param)).Unwrap()

	respData, err := logic.NewAliPayOrderLogic().AliPayOrderUnfreeze(param)
	if err != nil {
		log.Println("资金授权解冻失败", err, respData)
		Response(c)("资金授权解冻失败", CodeSuccess, err)(Error)
		return
	}
	Response(c)("", CodeSuccess, respData)(OK)

}

//订单信息同步
func OrderInfoSync(c *gin.Context) {
	param := &request.OrderInfoSync{}
	dingo.ErrorIf(c.Bind(param)).Unwrap()

	respData, err := logic.NewAliPayOrderLogic().AliPayOrderInfoSync(param)
	if err != nil {
		log.Println("订单信息同步失败", err, respData)
		Response(c)("订单信息同步失败", CodeSuccess, err)(Error)
		return
	}
	Response(c)("", CodeSuccess, respData)(OK)
}

//资金授权操作查询接口
func FundAuthOperationDetailQuery(c *gin.Context) {
	param := &request.FundAuthOperationDetailQuery{}
	dingo.ErrorIf(c.Bind(param)).Unwrap()

	respData, err := logic.NewAliPayOrderLogic().AliPayFundAuthOperationDetailQuery(param)
	if err != nil {
		log.Println("资金授权操作查询失败", err, respData)
		Response(c)("资金授权操作查询失败", CodeSuccess, err)(Error)
		return
	}
	Response(c)("", CodeSuccess, respData)(OK)
}
